/* eslint-disable no-array-constructor */
/* eslint-disable no-undef */
/* eslint-disable no-new-object */
/* eslint-disable eqeqeq */
/* eslint-disable no-tabs */
/* eslint-disable no-mixed-spaces-and-tabs */
var nmCryptokit = {
  // Release path: \\192.168.117.2\Release\SADK\Client\ZHY\CryptoKit
  chromeExtension: 'ligfbnbbknmdmnfkpnepcncdpljalgkd',
  productID: 'com.cfca.cryptokit.paperless.cmbchina',

  Browser: {
    IE: 'Internet Explorer',
    Edge: 'Edge',
    Chrome: 'Chrome',
    Safari: 'Safari',
    Firefox: 'Firefox'
  },

  // Encapsulate Chrome sendMessage callback to Promise
  _SendMessageforChrome: function (request) {
    var self = this
    return new Promise(function (resolve, reject) {
      // eslint-disable-next-line no-undef
      chrome.runtime.sendMessage(self.chromeExtension, request, function (response) {
			    if (response) {
				    // eslint-disable-next-line eqeqeq
				    if (response.errorcode == 0) {
            resolve(response)
				    } else {
            reject(response)
				    }
			    } else {
			        // eslint-disable-next-line no-new-object
			        var result = new Object()
			        result.errorcode = 1
			        // eslint-disable-next-line no-undef
			        result.result = chrome.runtime.lastError.message
			        reject(result)
			    }
		    })
    })
  },

  // Encapsulate Edge&Firefox event to Promise
  _SendMessagebyEvent: function (request) {
    var self = this
    var event = new CustomEvent(self.reqEventName, { detail: request })
    document.dispatchEvent(event)

    return new Promise(function (resolve, reject) {
      document.addEventListener(self.respEventName, function CallBack (e) {
        document.removeEventListener(e.type, CallBack)
        var eJson = JSON.parse(e.detail)
        if (eJson != null && eJson.errorcode == 0) {
          resolve(eJson)
        } else {
          reject(eJson)
        }
      }, false)
    })
  },

  _SendMessage: function (browser, requestJSON) {
	    var self = this
    if (self.Browser.Chrome == browser) {
      return self._SendMessageforChrome(requestJSON)
    } else {
      return self._SendMessagebyEvent(requestJSON)
    }
  },

  _checkExtension: function (browser) {
	    var self = this
    return new Promise(function (resolve, reject) {
      var result = new Object()
      if (self.Browser.Chrome == browser) {
        // chrome.runtime.sendMessage() could check extension  existence.
			    if (chrome.runtime) {
				    resolve(browser)
			    } else {
          result.errorcode = 2
          result.result = 'Extension does not exist!'
          reject(result)
			    }
      } else if (self.Browser.Edge == browser || self.Browser.Firefox == browser) {
        if (document.getElementById(self.extensionName)) {
          resolve(browser)
        } else {
          result.errorcode = 2
          result.result = 'Extension does not exist!'
          reject(result)
        }
      } else {
        result.errorcode = 3
        result.result = 'Only support Chrome Firefox and Edge'
        reject(result)
      }
    })
  },

  init: function (browser) {
    var self = this

    this.browser = browser
    this.extensionName = this.productID + '.extension'
    this.reqEventName = this.productID + '.request'
    this.respEventName = this.productID + '.response'

    return self._checkExtension(browser)
      .then(function (browser) {
        var request = new Object()
        request.action = 'connect'
        request.host = self.productID
        return self._SendMessage(browser, request)
      }).then(function () {
        var request = new Object()
        request.action = 'checkHost'
        return self._SendMessage(browser, request)
      })
  },

  uninit: function () {
    var self = this
    var request = new Object()
    request.action = 'disconnect'
    request.host = self.productID

    return self._SendMessage(this.browser, request)
  },

  getExtensionVersion: function () {
    var self = this
    var request = new Object()
    var funcInfo = new Object()

    funcInfo.function = 'getExtensionVersion'
    funcInfo.params = null
    request.action = 'getExtensionVersion'
    request.funcInfo = funcInfo

    return self._SendMessage(this.browser, request)
  },

  selectCertificate: function (bstrCertType, bstrDN, bstrSN, bstrCSP) {
    var self = this
    var request = new Object()
    var funcInfo = new Object()
    var paramArr = new Array()

    paramArr.push(bstrCertType)
    paramArr.push(bstrDN)
    paramArr.push(bstrSN)
    paramArr.push(bstrCSP)

    funcInfo.function = 'selectCertificate'
    funcInfo.params = paramArr

    request.action = 'invoke'
    request.funcInfo = funcInfo

    return self._SendMessage(this.browser, request)
  },

  getSignCertInfo: function (strInfoType) {
    var self = this
    var request = new Object()
    var funcInfo = new Object()
    var paramArr = new Array()

    paramArr.push(strInfoType)

    funcInfo.function = 'GetSignCertInfo'
    funcInfo.params = paramArr

    request.action = 'invoke'
    request.funcInfo = funcInfo

    return self._SendMessage(this.browser, request)
  },

  signMsgPKCS7: function (strSource, strSelectedAlg, bAttached) {
    var self = this
    var request = new Object()
    var funcInfo = new Object()
    var paramArr = new Array()

    paramArr.push(strSource)
    paramArr.push(strSelectedAlg)
    paramArr.push(bAttached)

    funcInfo.function = 'signMsgPKCS7'
    funcInfo.params = paramArr

    request.action = 'invoke'
    request.funcInfo = funcInfo

    return self._SendMessage(this.browser, request)
  },

  getLastErrorDesc: function () {
    var self = this
    var request = new Object()
    var funcInfo = new Object()

    funcInfo.function = 'GetLastErrorDesc'
    funcInfo.params = null

    request.action = 'invoke'
    request.funcInfo = funcInfo

    return self._SendMessage(this.browser, request)
	},

	signHashMsgPKCS7Detached: function (bstrSourceData, bstrHashAlg) {
		var self = this;
    var request = new Object();
    var funcInfo = new Object();
    var paramArr = new Array();
    var randomId = GenerateRandomId();

    paramArr.push(bstrSourceData);
    paramArr.push(bstrHashAlg);

    funcInfo.function = "SignHashMsgPKCS7Detached";
    funcInfo.params = paramArr;
    funcInfo.randomId = randomId;

    request.action = "invoke";
    request.funcInfo = funcInfo;

		return self._SendMessage(this.browser, request);
	}

}
export { nmCryptokit }

export function GenerateRandomId() {
    var charstring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
    var maxPos = charstring.length;
    var randomId = '';
    for (let i = 0; i < 10; i++) {
        randomId += charstring.charAt(Math.floor(Math.random() * maxPos));
    }
    return randomId;
}
